package com.student.enrollment.service.impl;

import com.student.common.entity.Enrollment;
import com.student.common.entity.Student;
import com.student.common.entity.Result;
import com.student.enrollment.service.EnrollmentService;
import com.student.enrollment.repository.EnrollmentRepository;
import com.student.enrollment.feign.StudentServiceClient;
import com.student.enrollment.feign.CourseServiceClient;
import com.student.common.entity.Course;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import org.springframework.data.domain.PageImpl;

/**
 * 选课服务实现类
 * 
 * @author student
 * @date 2025
 */
@Service
public class EnrollmentServiceImpl implements EnrollmentService {
    
    @Autowired
    private EnrollmentRepository enrollmentRepository;
    
    @Autowired
    private StudentServiceClient studentServiceClient;
    
    @Autowired
    private CourseServiceClient courseServiceClient;
    
    @Override
    public boolean selectCourse(String studentId, String courseId, String semester) {
        try {
            // 检查是否已经选过该课程
            Enrollment existingEnrollment = enrollmentRepository.findByStudentIdAndCourseIdAndSemester(studentId, courseId, semester);
            if (existingEnrollment != null) {
                // 如果已存在选课记录，检查状态
                if ("ENROLLED".equals(existingEnrollment.getStatus())) {
                    System.out.println("学生 " + studentId + " 已经选择了课程 " + courseId + " 在学期 " + semester);
                    return false; // 已经选课，不能重复选择
                } else if ("DROPPED".equals(existingEnrollment.getStatus())) {
                    // 如果之前退课了，可以重新选择
                    existingEnrollment.setStatus("ENROLLED");
                    existingEnrollment.setEnrollmentTime(LocalDateTime.now());
                    enrollmentRepository.save(existingEnrollment);
                    System.out.println("学生 " + studentId + " 重新选择了课程 " + courseId + " 在学期 " + semester);
                    return true;
                }
            }
            
            // 创建新的选课记录
            Enrollment enrollment = new Enrollment();
            enrollment.setStudentId(studentId);
            enrollment.setCourseId(courseId);
            enrollment.setSemester(semester);
            enrollment.setEnrollmentTime(LocalDateTime.now());
            enrollment.setStatus("ENROLLED");
            enrollment.setCreateTime(LocalDateTime.now());
            
            enrollmentRepository.save(enrollment);
            System.out.println("学生 " + studentId + " 成功选择了课程 " + courseId + " 在学期 " + semester);
            return true;
        } catch (Exception e) {
            System.err.println("选课失败: " + e.getMessage());
            e.printStackTrace();
            
            // 处理约束违反异常
            if (e.getMessage() != null && (
                e.getMessage().contains("uk_student_course") || 
                e.getMessage().contains("Duplicate entry") ||
                e.getMessage().contains("constraint"))) {
                System.out.println("重复选课，学生 " + studentId + " 已经选择了课程 " + courseId + " 在学期 " + semester);
                return false; // 重复选课
            }
            throw e; // 其他异常继续抛出
        }
    }
    
    @Override
    public boolean selectCourse(String studentId, String courseId, String semester, String enrollmentDate) {
        try {
            // 检查是否已经选过该课程
            Enrollment existingEnrollment = enrollmentRepository.findByStudentIdAndCourseIdAndSemester(studentId, courseId, semester);
            if (existingEnrollment != null) {
                // 如果已存在选课记录，检查状态
                if ("ENROLLED".equals(existingEnrollment.getStatus())) {
                    System.out.println("学生 " + studentId + " 已经选择了课程 " + courseId + " 在学期 " + semester);
                    return false; // 已经选课，不能重复选择
                } else if ("DROPPED".equals(existingEnrollment.getStatus())) {
                    // 如果之前退课了，可以重新选择
                    existingEnrollment.setStatus("ENROLLED");
                    // 使用传入的选课时间，如果没有则使用当前时间
                    if (enrollmentDate != null && !enrollmentDate.trim().isEmpty()) {
                        try {
                            LocalDateTime parsedDate = LocalDateTime.parse(enrollmentDate + "T00:00:00");
                            existingEnrollment.setEnrollmentTime(parsedDate);
                        } catch (Exception e) {
                            System.err.println("解析选课时间失败，使用当前时间: " + e.getMessage());
                            existingEnrollment.setEnrollmentTime(LocalDateTime.now());
                        }
                    } else {
                        existingEnrollment.setEnrollmentTime(LocalDateTime.now());
                    }
                    enrollmentRepository.save(existingEnrollment);
                    System.out.println("学生 " + studentId + " 重新选择了课程 " + courseId + " 在学期 " + semester + " 选课时间: " + enrollmentDate);
                    return true;
                }
            }
            
            // 创建新的选课记录
            Enrollment enrollment = new Enrollment();
            enrollment.setStudentId(studentId);
            enrollment.setCourseId(courseId);
            enrollment.setSemester(semester);
            // 使用传入的选课时间，如果没有则使用当前时间
            if (enrollmentDate != null && !enrollmentDate.trim().isEmpty()) {
                try {
                    LocalDateTime parsedDate = LocalDateTime.parse(enrollmentDate + "T00:00:00");
                    enrollment.setEnrollmentTime(parsedDate);
                } catch (Exception e) {
                    System.err.println("解析选课时间失败，使用当前时间: " + e.getMessage());
                    enrollment.setEnrollmentTime(LocalDateTime.now());
                }
            } else {
                enrollment.setEnrollmentTime(LocalDateTime.now());
            }
            enrollment.setStatus("ENROLLED");
            enrollment.setCreateTime(LocalDateTime.now());
            
            enrollmentRepository.save(enrollment);
            System.out.println("学生 " + studentId + " 成功选择了课程 " + courseId + " 在学期 " + semester + " 选课时间: " + enrollmentDate);
            return true;
        } catch (Exception e) {
            System.err.println("选课失败: " + e.getMessage());
            e.printStackTrace();
            
            // 处理约束违反异常
            if (e.getMessage() != null && (
                e.getMessage().contains("uk_student_course") || 
                e.getMessage().contains("Duplicate entry") ||
                e.getMessage().contains("constraint"))) {
                System.out.println("重复选课，学生 " + studentId + " 已经选择了课程 " + courseId + " 在学期 " + semester);
                return false; // 重复选课
            }
            throw e; // 其他异常继续抛出
        }
    }
    
    @Override
    public boolean dropCourse(String studentId, String courseId, String semester) {
        Enrollment enrollment = enrollmentRepository.findByStudentIdAndCourseIdAndSemester(studentId, courseId, semester);
        if (enrollment == null) {
            return false;
        }
        
        // 检查是否有成绩记录（这里简化处理，实际应该调用成绩服务检查）
        // 不删除数据，只修改状态为已退课
        enrollment.setStatus("DROPPED");
        enrollmentRepository.save(enrollment);
        return true;
    }
    
    @Override
    public Page<Enrollment> getStudentEnrollments(String studentId, String semester, Pageable pageable) {
        if (StringUtils.hasText(semester)) {
            return enrollmentRepository.findByStudentIdAndSemester(studentId, semester, pageable);
        }
        return enrollmentRepository.findByStudentId(studentId, pageable);
    }
    
    @Override
    public Page<Enrollment> getCourseEnrollments(String courseId, String semester, Pageable pageable) {
        if (StringUtils.hasText(semester)) {
            return enrollmentRepository.findByCourseIdAndSemester(courseId, semester, pageable);
        }
        return enrollmentRepository.findByCourseId(courseId, pageable);
    }
    
    @Override
    public Page<Enrollment> getEnrollmentList(Pageable pageable, String studentId, String courseId, String semester, String status) {
        if (StringUtils.hasText(studentId) || StringUtils.hasText(courseId) || 
            StringUtils.hasText(semester) || StringUtils.hasText(status)) {
            return enrollmentRepository.findByConditions(studentId, courseId, semester, status, pageable);
        }
        return enrollmentRepository.findAll(pageable);
    }
    
    @Override
    public Page<Map<String, Object>> getEnrollmentListWithDetails(Pageable pageable, String studentId, String courseId, String semester, String status) {
        Page<Enrollment> enrollmentPage = getEnrollmentList(pageable, studentId, courseId, semester, status);
        
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Enrollment enrollment : enrollmentPage.getContent()) {
            Map<String, Object> enrollmentMap = new HashMap<>();
            enrollmentMap.put("enrollmentId", enrollment.getEnrollmentId());
            enrollmentMap.put("studentId", enrollment.getStudentId());
            
            // 通过Feign客户端获取学生真实姓名
            String studentName = getStudentName(enrollment.getStudentId());
            enrollmentMap.put("studentName", studentName);
            
            enrollmentMap.put("courseId", enrollment.getCourseId());
            enrollmentMap.put("courseCode", enrollment.getCourseId()); // 课程编号
            
            // 通过Feign客户端获取课程真实名称
            String courseName = getCourseName(enrollment.getCourseId());
            enrollmentMap.put("courseName", courseName);
            enrollmentMap.put("semester", enrollment.getSemester());
            enrollmentMap.put("enrollmentDate", enrollment.getEnrollmentTime());
            enrollmentMap.put("status", enrollment.getStatus());
            enrollmentMap.put("createTime", enrollment.getCreateTime());
            resultList.add(enrollmentMap);
        }
        
        return new PageImpl<>(resultList, pageable, enrollmentPage.getTotalElements());
    }
    
    /**
     * 获取学生姓名
     */
    private String getStudentName(String studentId) {
        try {
            Result<Student> result = studentServiceClient.getStudentById(studentId);
            if (result != null && result.getCode() == 200 && result.getData() != null) {
                return result.getData().getName();
            }
        } catch (Exception e) {
            System.err.println("获取学生姓名失败: " + e.getMessage());
        }
        return "学生" + studentId; // 如果获取失败，返回默认值
    }
    
    /**
     * 获取课程名称
     */
    private String getCourseName(String courseId) {
        try {
            Result<Course> result = courseServiceClient.getCourseById(courseId);
            if (result != null && result.getCode() == 200 && result.getData() != null) {
                String courseName = result.getData().getCourseName();
                System.out.println("成功获取课程名称: " + courseId + " -> " + courseName);
                return courseName;
            } else {
                System.err.println("课程服务返回空数据: " + courseId);
            }
        } catch (Exception e) {
            System.err.println("获取课程名称失败: " + courseId + " - " + e.getMessage());
            // 如果是连接拒绝错误，提示用户检查课程服务状态
            if (e.getMessage() != null && e.getMessage().contains("Connection refused")) {
                System.err.println("课程服务连接被拒绝，请检查课程服务是否启动在端口8004");
            }
        }
        return "课程" + courseId; // 如果获取失败，返回默认值
    }
    
    @Override
    public Object getEnrollmentStatistics(String semester) {
        Map<String, Object> statistics = new HashMap<>();
        
        if (StringUtils.hasText(semester)) {
            long totalEnrollments = enrollmentRepository.countBySemester(semester);
            statistics.put("totalEnrollments", totalEnrollments);
            statistics.put("semester", semester);
        } else {
            long totalEnrollments = enrollmentRepository.count();
            statistics.put("totalEnrollments", totalEnrollments);
        }
        
        return statistics;
    }
    
    @Override
    public long getEnrollmentCount() {
        return enrollmentRepository.count();
    }
}
